// 查询和对比轮廓
#include "tabwin1.h"
#include "ui_tabwin1.h"
#include <QMenu>
using namespace cv;

void TabWin1::init2(){
    // // //表格
    standItemModel2 = new QStandardItemModel();
    ui->tableView_2->setModel(standItemModel2);    //挂载表格模型
    // 设置表格属性
    ui->tableView_2->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft);            //表头信息显示居中
    ui->tableView_2->setEditTriggers(QAbstractItemView::SelectedClicked);                 //设置表格属性(如只读，不能编辑)
    ui->tableView_2->setSelectionBehavior(QTableView::SelectRows);                        //整行选中
    ui->tableView_2->resizeColumnToContents(0);
    ui->tableView_2->scrollToBottom();
    ui->tableView_2->setContextMenuPolicy(Qt::CustomContextMenu);
    standItemModel2->setHorizontalHeaderLabels({"轮廓面积","轮廓特征"});
    connect(ui->tableView_2, &QTableView::customContextMenuRequested
            , this, &TabWin1::on_tableViewCustomContextMenuRequested2);
    connect(ui->lineEdit_2, &MainEdit::Slots_Click, this, &TabWin1::ImportData);
}

// 匹配轮廓特征
void TabWin1::contoursMatch(cv::Mat matImage, std::vector<cv::Point> &contourTmp, int a1, int a2, int a3, int b1, int b2, int b3, double scale){
    if(matImage.empty()) return;
    cv::Mat hsv, image;
    scale/=100.0f;  // 缩放比例，根据需要调整
    cv::resize(matImage, image, cv::Size(), scale,  scale,  cv::INTER_LINEAR);
    cv::cvtColor(image, hsv, cv::COLOR_BGR2HSV);
    cv::Scalar lower_red(a1,a2,a3); // 下限
    cv::Scalar upper_red(b1,b2,b3); // 上限
    cv::Mat mask;
    cv::inRange(hsv, lower_red, upper_red, mask);
    // 提取轮廓
    std::vector<std::vector<cv::Point>> contours_tmp;
    cv::findContours(mask, contours_tmp, cv::RETR_EXTERNAL, cv::CHAIN_APPROX_SIMPLE);
    // 对比轮廓,使用CONTOURS_MATCH_I3可以匹配缩放和旋转的图片
    int minNumIndex=-1;
    double minNum=999;
    for (int i = 0; i < contours_tmp.size(); ++i) {
        double matchNum = cv::matchShapes(contours_tmp[i],contourTmp,  CONTOURS_MATCH_I3, 0);
        if(matchNum<minNum){
            minNumIndex = i;
            minNum=matchNum;
        }
        qDebug() << i+1 << ":" << matchNum;
    }
    if(minNumIndex!=-1&&minNum<1.0){
        // 画出最匹配的轮廓
        QString str="Min Index:"+QString::number(minNumIndex) + ",num:" + QString::number(minNum);
        qDebug() << str;
        cv::drawContours(image, contours_tmp, (int)minNumIndex, cv::Scalar(255, 191, 0), 2);
        cv::Point textPos = cv::Point(contours_tmp[minNumIndex].at(0).x + 6, contours_tmp[minNumIndex].at(0).y - 6);
        cv::putText(image, std::to_string(minNumIndex+1), textPos, cv::FONT_HERSHEY_SIMPLEX, 0.8, cv::Scalar(250, 0, 255), 2, LINE_AA);
        showImage(str, image);
    }else{
        QMessageBox::information(this, u8"特征匹配", u8"特征匹配失败！最佳匹配index:"+QString::number(minNumIndex)+",number:"+QString::number(minNum));
    }
}

// 表格2-导入特征文件
void TabWin1::ImportData(){
    standItemModel2->clear();
    ui->tableView_2->setSortingEnabled(0);
    QString selectedFile = QFileDialog::getOpenFileName(this, "Open File", QDir::homePath(), "contoursDataFiles (*.txt);");
    if(!selectedFile.isEmpty()){
        ui->lineEdit_2->setText(selectedFile);
        QFile file(selectedFile);
        if (!file.open(QIODevice::ReadOnly | QIODevice::Text)) {
            ui->lineEdit_2->setText(selectedFile+"-打开失败");
            return; // 返回空的QList
        }
        QTextStream in(&file);
        QString line;
        // 获取第一行
        if(!in.atEnd()){
            line = in.readLine();
            QList<QString> strList = line.split(";");
            if(line.size()<6){
                ui->lineEdit_2->setText("文件格式错误."+selectedFile);
                file.close();
                return;
            }
            ui->spinBox->setValue(strList[0].toInt());
            ui->horizontalSlider->setValue(strList[0].toInt());
            ui->spinBox_2->setValue(strList[1].toInt());
            ui->horizontalSlider_2->setValue(strList[1].toInt());
            ui->spinBox_3->setValue(strList[2].toInt());
            ui->horizontalSlider_3->setValue(strList[2].toInt());
            ui->spinBox_13->setValue(strList[3].toInt());
            ui->horizontalSlider_13->setValue(strList[3].toInt());
            ui->spinBox_14->setValue(strList[4].toInt());
            ui->horizontalSlider_14->setValue(strList[4].toInt());
            ui->spinBox_15->setValue(strList[5].toInt());
            ui->horizontalSlider_15->setValue(strList[5].toInt());
            ui->horizontalSlider_16->setValue(strList[6].toInt());
        }
        // 后面的
        while (!in.atEnd()) {
            line = in.readLine(); // 读取一行
            QList<QString> strList = line.split("\t");
            if(strList.size()==2){
                int row=standItemModel2->rowCount();
                for (int col = 0; col < strList.size(); ++col) {
                    if(col==0){
                        QStandardItem *item=new QStandardItem(strList[col]);
                        item->setData(strList[col].toDouble(), Qt::EditRole);  // 根据数值排序
                        standItemModel2->setItem(row, col, item);
                        continue;
                    }
                    standItemModel2->setItem(row, col, new QStandardItem(strList[col]));
                }
            }
        }
        file.close();
        ui->tableView_2->resizeColumnToContents(0);
        ui->tableView_2->scrollToBottom();
        ui->tableView_2->setSortingEnabled(1);
    }else{
        ui->lineEdit_2->setText("");
    }
}

// 列表转轮廓特征
bool TabWin1::itemToContour(QString &str, std::vector<cv::Point> &coutour){
    QList<QString> strList = str.split(";");
    for (int i = 0; i < strList.size(); ++i) {
        QList<QString> strList2 = strList[i].split(",");
        if(strList2.size()!=2) continue;
        coutour.push_back({strList2[0].toInt(), strList2[1].toInt()});
    }
    return !coutour.empty();
}

// 表格2右键选项
void TabWin1::on_tableViewCustomContextMenuRequested2(const QPoint &pos)
{
    Q_UNUSED(pos);
    QMenu menu;
    //添加右键菜单的选项
    menu.addAction("特征对比");
    menu.addAction("标记选中");
    menu.addAction("...");
    connect(&menu, &QMenu::triggered, [=](QAction *action){
        if("标记选中"==action->text()){
            signContours();
        }
        if("特征对比"==action->text()){
            QModelIndex currentIndex = ui->tableView_2->selectionModel()->currentIndex();
            if(currentIndex.isValid()){
                QString itemStr=standItemModel2->item(currentIndex.row(), 1)->text();
                std::vector<cv::Point> coutour;
                if(itemToContour(itemStr, coutour)){
                    qDebug() << coutour.size();
                    contoursMatch(srcImage, coutour,
                                    ui->horizontalSlider->value()/2,    // 因为QColor使用的Hue是0-359，opencv使用的是0-179，所以需要除以二
                                    ui->horizontalSlider_2->value(),
                                    ui->horizontalSlider_3->value(),
                                    ui->horizontalSlider_13->value()/2, // 因为QColor使用的Hue是0-359...
                                    ui->horizontalSlider_14->value(),
                                    ui->horizontalSlider_15->value(),
                                    ui->horizontalSlider_16->value());
                }
                else{
                    this->setStatusTip("特征格式错误!参考格式:\"x1,y1;x2,y2;...\"");
                    QMessageBox::warning(this, u8"错误", u8"特征格式错误!参考格式:\"x1,y1;x2,y2;...\"");
                }
            }
        }
    });
    // 显示menu菜单并设置其显示位置为鼠标位置
    menu.exec(QCursor::pos());
}
